package server;

import game.DAO;
import game.SuperGame;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import player.Player;

public class Server {

	// list of games in progress or pending
	static List<SuperGame> gamesList = new ArrayList<SuperGame>();

	public static void main(String[] args) {
		// create server inet address
		InetSocketAddress serverAddr = new InetSocketAddress("localhost", 8888);

		// player socket
		Socket clientSocket;

		// server socket initialization
		ServerSocket socketServer = null;

		// boolean using to stop the server (when value equals true)
		boolean terminated = false;

		// reading and writing flows
		InputStream in;
		OutputStream out;
		BufferedReader bufIn = null;
		BufferedWriter bufOut = null;

		// server socket instantiation
		try {
			socketServer = new ServerSocket();
			socketServer.bind(serverAddr);

		} catch (IOException e1) {
			e1.printStackTrace();
		}

		// the server runs as long as we don't stop
		while (!terminated) {
			try {

				// wait for a player
				clientSocket = socketServer.accept();

				in = clientSocket.getInputStream();
				out = clientSocket.getOutputStream();
				bufIn = new BufferedReader(new InputStreamReader(in));
				bufOut = new BufferedWriter(new OutputStreamWriter(out));

				// by connecting the player gives directly his nickname and
				// the games he wants to play
				String tmpMsg = bufIn.readLine();
				String[] split = tmpMsg.split("_");
				String tmpPseudo = split[0];
				// get game
				String tmpGame = split[1];
				String udpServerAdresse = split[2];
				int udpServerPort = Integer.parseInt(split[3]);

				// boolean using to know if the player has been inserted into a
				// game
				boolean isAdded = false;

				// check if there is already a waiting player for this game
				for (SuperGame sg : gamesList) {

					// find the corresponding game
					if (sg.getKindOfGame().equals(tmpGame)) {

						// if the game hasn't been started, it means there are
						// waiting players
						if (!sg.isStarted()) {

							// add the new player
							sg.addNewPlayer(new Player(tmpPseudo, clientSocket,
									udpServerAdresse, udpServerPort));

							// change the value of isAdded to true which means
							// the
							// player has been added to an existed game and so
							// avoid
							// creating a new game
							isAdded = true;

							// check if the number of players needed
							// to launch a new game has been reached
							if (sg.getListPlayer().size() == sg.getNbJoueur()) {
								sg.setStarted(true);
								new Thread(new Referee(sg)).start();
							}
							break;
						}
					}
				}

				// if there are not waiting players for this game, create
				// a new game for this player and put him on the pending list
				if (!isAdded) {
					// instantiate the corresponding game
					gamesList.add(new DAO().getTypeOfGame(tmpGame, new Player(
							tmpPseudo, clientSocket, udpServerAdresse,
							udpServerPort)));
					bufOut.write("waitOtherPlayer");
					bufOut.newLine();
					bufOut.flush();
				}

				// reset the variable isAdded
				isAdded = false;

			} catch (IOException e) {
				e.printStackTrace();
				System.out
						.println("An error has been occured while connecting to the server socket");
			}
		}

		// close server socket
		try {
			socketServer.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.out
					.println("An error has been occured while ending the connection to the server socket");
		}
	}
}
